<template>

  <div class="">
    <el-tree ref="treeRef" :data="data" node-key="id" default-expand-all @node-drag-start="handleDragStart"
      @node-drag-enter="handleDragEnter" @node-drag-leave="handleDragLeave" @node-drag-over="handleDragOver"
      @node-drag-end="handleDragEnd" @node-drop="handleDrop" draggable :allow-drop="allowDrop" :allow-drag="allowDrag"
      @node-contextmenu="openRightMenu">

      <template #default="{ node, data }">
        <div class="custom-tree-node" :data-id="data.id" :id="data.id" @drop="treeDrop(data, $event)">
          <span>测试{{ node.label }}</span>
        </div>
      </template>
    </el-tree>
    <div ref="editor" contenteditable class="editor-box"></div>

    <!--右键显示的菜单组件-->
    <div v-show="treeRightMenuShow" class="tree-right-menu" ref="treeRightMenu" :style="{ ...rightTreeMenuStyle }">
      <div v-for="(item, key) of rightBtn" :key="key" @click="rightMenuClick(item, key)">
        <span :class="[{ 'disabled': item.disabled }, 'right-menu-item']" disabled>{{ item.name }}</span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      data: [{
        id: 1,
        label: '一级 1',
        children: [{
          id: 4,
          label: '二级 1-1',
          children: [{
            id: 9,
            label: '三级 1-1-1'
          }, {
            id: 10,
            label: '三级 1-1-2'
          }]
        }]
      }, {
        id: 2,
        label: '一级 2',
        children: [{
          id: 5,
          label: '二级 2-1'
        }, {
          id: 6,
          label: '二级 2-2'
        }]
      }, {
        id: 3,
        label: '一级 3',
        children: [{
          id: 7,
          label: '二级 3-1'
        }, {
          id: 8,
          label: '二级 3-2',
          children: [{
            id: 11,
            label: '三级 3-2-1'
          }, {
            id: 12,
            label: '三级 3-2-2'
          }, {
            id: 13,
            label: '三级 3-2-3'
          }]
        }]
      }],
      defaultProps: {
        children: 'children',
        label: 'label'
      },
      editor: '',
      treeRightMenuShow: false,
      rightTreeMenuStyle: {},
      copyNode: {},
      activeNode: {},
      rightBtn: {
        'edit': {
          name: '编辑',
          disabled: false
        },
        'delete': {
          name: '删除',
          disabled: false
        },
        'copy': {
          name: '复制',
          disabled: false
        },
        'paste': {
          name: '粘贴',
          disabled: true
        }
      },
      fileList: [{ name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' }, { name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100' }]
    };
  },
  methods: {
    handleDragStart(node, ev) {
      console.log('drag start', node, ev);
    },
    handleDragEnter(draggingNode, dropNode, ev) {
      console.log('tree drag enter: ', dropNode.label, ev);
    },
    handleDragLeave(draggingNode, dropNode, ev) {
      console.log('tree drag leave: ', dropNode.label, ev);
    },
    handleDragOver(draggingNode, dropNode, ev) {
      console.log('tree drag over: ', dropNode.label, ev);
    },
    handleDragEnd(draggingNode, dropNode, dropType, ev) {
      console.log('tree drag end: ', dropNode && dropNode.label, dropType, ev);
    },
    handleDrop(draggingNode, dropNode, dropType, ev) {
      ev.preventDefault()
      console.log('tree drop: ', dropNode.label, dropType, ev);
      console.error('拖拽结束')
    },
    allowDrop(draggingNode, dropNode, type) {

      // const files = event.dataTransfer.files;
      // console.log(event, "ev", files);
      // ev.preventDefault()
      if (dropNode.data.label === '二级 3-1') {
        return type !== 'inner';
      } else {
        return true;
      }
    },
    allowDrag(draggingNode) {
      return draggingNode.data.label.indexOf('三级 3-2-2') === -1;
    },
    // 拖拽上传
    treeDrop(data, event) {
      event.preventDefault()
      const editor = this.$refs.editor
      const files = event.dataTransfer.files;
      const filesList = []
      if (files.length > 0) {
        for (let i = 0; i < files.length; i++) {
          const file = files[i]; // 获取文件对象
          const reader = new FileReader(); // 创建FileReader对象
          console.log(file,'file')
          // 将文件读取为DataURL格式
          reader.readAsDataURL(file);
          // reader.readAsArrayBuffer(file);
          // 当文件读取完成时，执行以下操作
          reader.onload = (event) => {
            console.log(event,'event')
            const result = event.target.result
            // 转成blob
            let blob = new Blob([event.target.result], { type: file.type });
            // let blobURL = window.URL.createObjectURL(blob); // 创建URL
            // window.open(blobURL)

            // 转成base64
            console.log(result,'result',blob); // base64编码的文件数据
            filesList[i] = {
              id: data.id,
              name: file.name,
              label: data.label,
              data: result
            }
            // 创建一个img元素
            const img = document.createElement('img');
            // 将读取到的文件内容赋值给img的src属性
            img.src = event.target.result;
            // 将img元素添加到editor元素中
            editor.appendChild(img)

          };

          reader.onerror = function (event) {
            console.error('文件读取错误: ', event.target.error);
          };
        }

      }
      console.log(filesList, 'filesList')
    },
    // 右键菜单
    openRightMenu(event, data) {
      this.activeNode = data
      this.treeRightMenuShow = true
      //防止右键菜单底部被覆盖 --可以自己根据右键菜单的高度调整
      let jianPx = 0
      if (document.documentElement.clientHeight - event.pageY < 200) {
        jianPx = this.$refs.treeRightMenu.getBoundingClientRect().height - 15
      }
      //右键菜单的位置
      this.rightTreeMenuStyle = { top: event.pageY - jianPx + 'px', left: event.pageX + 'px' }
      //点击页面其他地方关闭右键菜单
      document.addEventListener('click', (e) => {
        const { className } = e.target
        if (!className.includes('right-menu-item')) {
          this.hideRightMenu()
        }
      })
      // 复制node节点,不能在当前复制NODE节点上粘贴
      if (this.copyNode.id === this.activeNode.id) {
        this.editRightBtn('paste', { disabled: true })
      } else {
        this.editRightBtn('paste', { disabled: false })
      }
    },
    hideRightMenu() {
      this.treeRightMenuShow = false
      // 关闭点击页面其他地方关闭右键菜单的监听
      document.removeEventListener('click', this.hideRightMenu)
    },
    rightMenuClick(item, type) {
      const treeRef = this.$refs.treeRef;
      const copyNode = this.copyNode
      const activeNode = this.activeNode
      switch (type) {
        case 'copy':
          this.copyNode = this.activeNode
          this.editRightBtn('paste', { disabled: false })
          break;
        case 'paste':
          if (copyNode.id && activeNode.id) {
            treeRef.append(copyNode, this.activeNode)
            this.editRightBtn('paste', { disabled: true })
          }
          break;
        default:
          console.log('没有选择任何操作');
      }
      this.hideRightMenu()
    },
    // 改变右键菜单按钮状态
    editRightBtn(type, data) {
      this.$set(this.rightBtn, type, {
        ...this.rightBtn[type],
        ...data
      })

    }
  }
};
</script>
<style lang="scss" scoped>
.tree-right-menu {
  position: fixed;
  width: 10%;
  box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
  z-index: 1000;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: flex-start;
  background: #fff;
  border-radius: 4px;
  padding: 5px 0;

  div {
    width: 100%;

    span {
      display: block;
      padding: 5px 0;
      cursor: pointer;


      &:hover {
        background: #f5f7fa;
      }

      &.disabled {
        background: none;
        color: #ccc;
      }
    }

  }

}

.disabled {
  color: #ccc;
}
</style>